package org.osami.phidget.proxy;

import java.util.Collection;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Property;
import org.apache.felix.ipojo.annotations.Validate;

import org.apache.felix.ipojo.handlers.event.publisher.Publisher;
import org.osami.gateway.sensor.Sense;
import org.osami.gateway.sensor.SenseData;
import org.osami.gateway.sensor.SenseNode;

import com.phidgets.InterfaceKitPhidget;
import com.phidgets.PhidgetException;
import com.phidgets.event.SensorChangeEvent;
import com.phidgets.event.SensorChangeListener;

@Component(name = "PhidgetProxyFactory")
public class PhidgetProxy implements SenseNode {
	@Property(name = "id")
	String m_id;

	@Property(name = "instance")
	InterfaceKitPhidget m_phidget;

	@Validate
	void start() {
		System.out.println("Phidget proxy created.");

		if (m_phidget != null) {
			int l_triggerValue = 50;

			try {
				m_phidget.setSensorChangeTrigger(0, l_triggerValue);
				m_phidget.setSensorChangeTrigger(1, l_triggerValue);
				m_phidget.setSensorChangeTrigger(7, l_triggerValue);
			} catch (PhidgetException e) {
				e.printStackTrace();
			}
			

			m_phidget.addSensorChangeListener(new SensorChangeListener() {

				public void sensorChanged(SensorChangeEvent arg0) {
					notifyEventAdmin(arg0);

				}
			});
		}
	}

	protected void notifyEventAdmin(SensorChangeEvent arg0) {
		System.out.println(String.format("Sensor %s: value=%s",arg0.getIndex(), arg0.getValue()));
		
		int l_value = arg0.getValue();
		String l_unit = resolveSensorUnit(arg0.getIndex());		
		
		PhidgetSenseData l_data = new PhidgetSenseData(l_value,"temperatur",l_unit,m_id,System.currentTimeMillis()); // TODO: change type
		m_dataPublisher.sendData(l_data);

	}

	@Invalidate
	void stop() {
		System.out.println("Phidget proxy stopped.");
	}

	@org.apache.felix.ipojo.handlers.event.Publisher(topics = SenseNode.TOPIC_PREFIX+"org.osami.phidget.proxy.PhidgetSenseData", data_key = "sensor-data", name = "PhidgetDataPublisher")
	Publisher m_dataPublisher;

	public Collection<SenseData> getData() {
		// TODO Auto-generated method stub
		return null;
	}

	public SenseData getData(String senseName) throws IllegalArgumentException {
		int l_sensorID = resolveSensorId(senseName);

		int l_value = 0;
		String l_unit = resolveSensorUnit(senseName); // TODO: make generic

		try {
			l_value = m_phidget.getSensorValue(l_sensorID);
		} catch (PhidgetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return new PhidgetSenseData(l_value,"temperatur", l_unit,senseName,System.currentTimeMillis()); // TODO: change "temperatur" 
	}

	public String getId() {
		return m_id;
	}

	public Collection<Sense> getSense() {
		return null;
	}

	public String getTopic() {
		return TOPIC_PREFIX;
	}

	public Long uptime() {
		// TODO Auto-generated method stub
		return null;
	}

	private enum SenseNodeIdentifier {
		X, Y, distance;

	}

	private int resolveSensorId(String param) {
		int l_result = -1;

		if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.X) {
			l_result = 0;
		} else if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.Y) {
			l_result = 1;
		} else if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.distance) {
			l_result = 7;
		}

		return l_result;
	}

	private String resolveSensorUnit(String param) {
		String l_result = "default";

		if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.X) {
			// l_result = 0;
		} else if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.Y) {
			// l_result = 1;
		} else if (SenseNodeIdentifier.valueOf(param) == SenseNodeIdentifier.distance) {
			l_result = "cm";
		}

		return l_result;
	}
	
	private String resolveSensorUnit(int param) {
		String l_result = "default";

		if (param == 0) {
			// l_result = 0;
		} else if (param == 1) {
			// l_result = 1;
		} else if (param == 7) {
			l_result = "cm";
		}

		return l_result;
	}

}
	